home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / SETVOL.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  4KB  |  189 lines

  1. /*
  2. **  SETVOL.C - set, change, or kill a disk volume label
  3. **
  4. **  public domain demo by Bob Stout
  5. **  DOS 5 enhancements suggested by Keith Beedle
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <dos.h>
  12. #include <io.h>
  13.  
  14. #define NUL '\0'
  15.  
  16. #if defined(__TURBOC__)
  17.  #pragma option -a-
  18.  #include <dir.h>
  19.  #define _dos_findfirst(f,a,b) findfirst(f,b,a)
  20.  #define _dos_findnext(b) findnext(b)
  21.  #define find_t ffblk
  22.  #define _A_VOLID FA_LABEL
  23.  #define attrib ff_attrib
  24.  #define name ff_name
  25.  #define size ff_size
  26.  #define wr_time ff_time
  27.  #define wr_date ff_date
  28.  #define dos_creat _creat
  29. #else
  30.  #include <direct.h>
  31.  #if defined(__ZTC__)
  32.   #pragma ZTC align 1
  33.  #else /* MSC/QC/WATCOM/METAWARE */
  34.   #pragma pack(1)
  35.   int dos_creat(const char *fname, unsigned attrib)
  36.   {
  37.         int fd;
  38.  
  39.         if (_dos_creat(fname, attrib, &fd))
  40.                 return -1;
  41.         else    return fd;
  42.   }
  43.  #endif
  44.  struct fcb {
  45.          char   fcb_drive;
  46.          char   fcb_name[8];
  47.          char   fcb_ext[3];
  48.          short  fcb_curblk;
  49.          short  fcb_recsize;
  50.          long   fcb_filsize;
  51.          short  fcb_date;
  52.          char   fcb_resv[10];
  53.          char   fcb_currec;
  54.          long   fcb_random;
  55.  };
  56.  
  57.  struct xfcb {
  58.          char           xfcb_flag;
  59.          char           xfcb_resv[5];
  60.          char           xfcb_attr;
  61.          struct fcb     xfcb_fcb;
  62.  };
  63. #endif
  64.  
  65. #include "dos5boot.h"   /* SNIPPETS file with DOS 5 boot record structure  */
  66.  
  67. /*
  68. **  NOTE: The following use functions in two other SNIPPETS files,
  69. **        ABSDISK.ASM & ABSDISKC.C
  70. */
  71.  
  72. int AbsDiskRead(unsigned short, size_t, size_t, void *);
  73. int AbsDiskWrite(unsigned short, size_t, size_t, void *);
  74.  
  75. /*
  76. **  Erase an existing volume label
  77. */
  78.  
  79. void vol_kill(char *fname)
  80. {
  81.       union REGS regs;
  82.       struct SREGS sregs;
  83.       struct xfcb buf;
  84.  
  85.       /* Parse the filename into an FCB               */
  86.  
  87.       segread(&sregs);
  88.       regs.h.ah = 0x29;
  89.       regs.h.al = 0;
  90.       regs.x.si = (unsigned)fname;
  91.       regs.x.di = (unsigned)&buf.xfcb_fcb;
  92.       sregs.es  = sregs.ds;
  93.       intdosx(®s, ®s, &sregs);
  94.  
  95.       /* Volume labels require extended FCB's         */
  96.  
  97.       buf.xfcb_flag = 0xff;
  98.       buf.xfcb_attr = _A_VOLID;
  99.  
  100.       /* Delete the old label                         */
  101.  
  102.       regs.h.ah = 0x13;
  103.       regs.x.dx = (unsigned)&buf;
  104.       intdos(®s, ®s);
  105. }
  106.  
  107. /*
  108. **  Create a new volume label
  109. */
  110.  
  111. void setvol(char *label)
  112. {
  113.       int fd;
  114.       char new_label[13];     /* name + ext + '.' + NUL       */
  115.       struct find_t finfo;
  116.       union REGS regs;
  117.  
  118.       /*
  119.       **  Change to root directory.
  120.       **
  121.       **  NOTE: To make this more robust, use pushdir() & popdir(),
  122.       **  also from SNIPPETS.
  123.       */
  124.       
  125.       chdir("\\");
  126.  
  127.       /* If drive is already labeled, remove it               */
  128.  
  129.       if (0 == _dos_findfirst("*.*", _A_VOLID, &finfo)) do
  130.       {
  131.             if (_A_VOLID & finfo.attrib)
  132.                   break;
  133.       } while (0 == _dos_findnext(&finfo));
  134.  
  135.       if (_A_VOLID & finfo.attrib)
  136.             vol_kill(finfo.name);
  137.  
  138.       strcpy(new_label, label);
  139.       if (8 < strlen(label))
  140.       {
  141.             new_label[8] = '.';
  142.             strcpy(&new_label[9], &label[8]);
  143.       }
  144.  
  145.       fd = dos_creat(new_label, _A_VOLID);/* Create new label */
  146.       close(fd);
  147.  
  148.       /*
  149.       **  For DOS 5.0 replace the boot record too.
  150.       */
  151.  
  152.       if(_osmajor > 3)
  153.       {
  154.             int index;
  155.             B_REC boot_record;
  156.  
  157.             AbsDiskRead(0, 1, 0, &boot_record);
  158.             if(0 == strcmp(boot_record.bsOemName, "MSDOS5.0"))
  159.             {
  160.                   index = 0;
  161.                   while (NUL != label[index])
  162.                   {
  163.                         boot_record.bsVolumeLabel[index] = label[index];
  164.                         index++;
  165.                   }
  166.                   for(index; index < 11; index++)
  167.                         boot_record.bsVolumeLabel[index] = 0x20;
  168.                   AbsDiskWrite(0, 1, 0, &boot_record);
  169.             }
  170.       }
  171.       /*
  172.       **  NOTE: If you used pushdir() above, use popdir() here.
  173.       */
  174. }
  175.  
  176. #ifdef TEST
  177.  
  178. void main(int argc, char *argv[])
  179. {
  180.       if (2 > argc)
  181.       {
  182.             puts("\aUsage: SETVOL new_name");
  183.             abort();
  184.       }
  185.       setvol(argv[1]);
  186. }
  187.  
  188. #endif
  189.